home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: d üR)Ëç m" ü£¶2.1 1999/08/19 14:31:53 lhecking Exp $
- *
- */
-
- /* GNUPLOT - doc2info.c */
-
- /*[
- * Copyright 1986 - 1993, 1998 Thomas Williams, Colin Kelley
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the complete modified source code. Modifications are to
- * be distributed as patches to the released version. Permission to
- * distribute binaries produced by compiling modified sources is granted,
- * provided you
- * 1. distribute the corresponding source modifications from the
- * released version in the form of a patch file along with the binaries,
- * 2. add special version identification to distinguish your version
- * in addition to the base release version number,
- * 3. provide your name and address as the primary contact for the
- * support of your modified version, and
- * 4. retain our contact information in regard to use of the base
- * software.
- * Permission to distribute the released version of the source code along
- * with corresponding source modifications in the form of a patch file is
- * granted with same provisions 2 through 4 for binary distributions.
- *
- * This software is provided "as is" without express or implied warranty
- * to the extent permitted by applicable law.
- ]*/
-
- /*
- * doc2info.c -- program to convert Gnuplot .DOC format to
- * (Emacs -) Info-file format
- *
- * Created by Stefan Bodewig from doc2gih by Thomas Williams
- * and doc2html by Russel Lang
- * 1/29/1996
- *
- * usage: doc2info gnuplot.doc gnuplot.info
- *
- */
-
- /* note that tables must begin in at least the second column to */
- /* be formatted correctly and tabs are forbidden */
-
- #ifdef HAVE_CONFIG_H
- # include "config.h"
- #endif
-
- #include "ansichek.h"
- #include "stdfn.h"
-
- #define MAX_LINE_LEN 1023
-
- #include "doc2x.h"
- #include "xref.h"
-
- struct BUFFER { /* buffer to reformat paragraphs with xrefs */
- char *content;
- struct BUFFER *next;
- struct BUFFER *prev;
- };
-
- struct XREFLIST { /* a list of xrefs allready mentioned in this node */
- struct LIST *ref;
- struct XREFLIST *next;
- struct XREFLIST *prev;
- };
-
- /* xref.c */
- extern struct LIST *list;
- extern struct LIST *head;
-
- extern struct LIST *keylist;
- extern struct LIST *keyhead;
-
- extern int maxlevel;
- extern int listitems;
-
- char title[MAX_LINE_LEN+1];
- char ifile[MAX_LINE_LEN+1];
- char ofile[MAX_LINE_LEN+1];
- struct XREFLIST *refhead = NULL;
-
- void convert __PROTO((FILE *, FILE *));
- void process_line __PROTO((char *, FILE *));
- void node_head __PROTO((char *, char *, char *, char *, FILE *));
- void name_free __PROTO((char **));
- char **name_alloc __PROTO(());
- void clear_buffer __PROTO((struct BUFFER *, FILE *));
- int inxreflist __PROTO((struct LIST *));
- void xref_free __PROTO((void));
-
- int main(argc, argv)
- int argc;
- char **argv;
- {
- FILE *infile;
- FILE *outfile;
- infile = stdin;
- outfile = stdout;
-
- if (argc > 3) {
- fprintf(stderr, "Usage: %s [infile [outfile]]\n", argv[0]);
- exit(EXIT_FAILURE);
- }
- if (argc >= 2) {
- strcpy(ifile, argv[1]);
- if ((infile = fopen(argv[1], "r")) == (FILE *) NULL) {
- fprintf(stderr, "%s: Can't open %s for reading\n",
- argv[0], argv[1]);
- exit(EXIT_FAILURE);
- }
- } else
- safe_strncpy(ifile, "gnuplot.doc", sizeof(ifile)); /* default value */
- if (argc == 3) {
- safe_strncpy(ofile, argv[2], sizeof(ofile));
- if ((outfile = fopen(argv[2], "w")) == (FILE *) NULL) {
- fprintf(stderr, "%s: Can't open %s for writing\n",
- argv[0], argv[2]);
- exit(EXIT_FAILURE);
- }
- } else
- safe_strncpy(ofile, "gnuplot.info", sizeof(ofile)); /* default value */
-
- safe_strncpy(title, ofile, sizeof(title));
- strtok(title, "."); /* without type */
- convert(infile, outfile);
- exit(EXIT_SUCCESS);
- }
-
-
- void convert(a, b)
- FILE *a, *b;
- {
- static char line[MAX_LINE_LEN+1];
-
- parse(a);
-
- refhead = (struct XREFLIST *) xmalloc(sizeof(struct XREFLIST));
- refhead->next = refhead->prev = NULL;
-
- /* Info header */
- fprintf(b, "\
- This file is %s created by doc2info from %s.\n\
- \n\
- START-INFO-DIR-ENTRY\n\
- * Gnuplot: (gnuplot). Gnuplot plotting program\n\
- END-INFO-DIR-ENTRY\n\n",
- ofile, ifile);
-
- /* and Top node */
- node_head(NULL, NULL, head->next->string, NULL, b);
-
- while (get_line(line, sizeof(line), a)) {
- process_line(line, b);
- }
- list_free();
- free(refhead);
- }
-
- /*
- * scans the lines for xrefs, creates new nodes and prints or ignores
- * the rest.
- *
- * Info xrefs are visible. Therefore we have to reformat the paragraphs
- * containing them. All lines of the paragraph are written into a buffer
- * and printed at the end of the paragraph.
- */
- void process_line(line, b)
- char *line;
- FILE *b;
- {
- static int line_count = 0;
- struct LIST *node; /* current node */
- static struct LIST *prev = NULL; /* previous node */
- int level; /* current level */
- static char **up = NULL; /* Array with node names */
- static char **pre = NULL;
- char topic[MAX_LINE_LEN+1]; /* for xrefs */
- int i, j, k, l;
- static int inref = FALSE; /* flags */
- static int inbold = FALSE;
- static struct BUFFER *buffer; /* buffer to hold the lines of a paragraph */
- static struct BUFFER *buf_head = NULL;
- int inbuf = 0; /* offset into buffer */
- char line2[3*MAX_LINE_LEN+1]; /* line of text with added xrefs */
- struct LIST *reflist;
- static struct XREFLIST *lastref = NULL; /* xrefs that are already mentioned in this node */
-
- line2[0] = NUL;
- if (!prev) /* last node visited */
- prev = head;
- if (!lastref)
- lastref = refhead;
- if (!up) { /* Names of `Prev:' and `Up:' nodes */
- up = name_alloc();
- pre = name_alloc();
- strcpy(up[0], "(dir)");
- strcpy(up[1], "Top");
- strcpy(pre[1], "(dir)");
- strcpy(pre[2], "Top");
- }
- line_count++;
-
- if (line[0] == ' ') /* scan line for xrefs */
- for (i = 0; line[i] != NUL; ++i)
- if (line[i] == '`') { /* Reference or boldface (ignore the latter) */
- if (!inref && !inbold) {
- k = i + 1; /* next character */
- j = 0; /* index into topic */
- while (line[k] != '`' && line[k] != NUL)
- topic[j++] = line[k++];
- topic[j] = NUL;
-
- /* try to find the xref */
- reflist = lookup(topic);
- if (reflist) {
- /* now we have the (key-)list-entry */
- /* convert it to a list-entry that represents a node */
- reflist = lkup_by_number(reflist->line);
- }
- /* not interested in xrefs pointing to `Top' or same node */
- /* we want only one reference per topic in node */
- if (reflist && reflist->level != 0 && reflist != prev && !inxreflist(reflist)) {
- /* new entry to xreflist */
- lastref->next = (struct XREFLIST *) xmalloc(sizeof(struct XREFLIST));
- lastref->next->prev = lastref;
- lastref = lastref->next;
- lastref->ref = reflist;
- lastref->next = NULL;
- if (!buf_head) { /* No buffer yet */
- buf_head = (struct BUFFER *) xmalloc(sizeof(struct BUFFER));
- buffer = buf_head;
- buffer->prev = NULL;
- buffer->next = NULL;
- }
- /* eliminate leading spaces of topic */
- for (j = 0; isspace((int) reflist->string[j]); ++j);
- /* encountered end of line */
- if (line[k] == NUL) {
- if (line[k - 1] == '\n') /* throw away new-lines */
- line[--k] = NUL;
- /* insert xref into line */
- sprintf(line2, "%s%s (*note %s:: )", line2, line + inbuf, reflist->string + j);
- inref = TRUE;
- /* line is done */
- break;
- }
- /* eliminate spaces before the second ` */
- if (isspace((int) line[k - 1]))
- for (l = k - 1; line[l] != NUL; ++l)
- line[l] = line[l + 1];
-
- /* let `plot`s look nicer */
- if (isalpha((int) line[k + 1]))
- ++k;
- sprintf(line2, "%s%.*s (*note %s:: )", line2, k - inbuf + 1, line + inbuf, reflist->string + j);
- /* line2 contains first inbuf characters of line */
- i = inbuf = k;
- } else { /* found no reference */
- inbold = TRUE;
- }
- } else {
- if (inref) /* inref || inbold */
- inref = FALSE;
- else
- inbold = FALSE;
- }
- }
- /* just copy normal characters of line with xref */
- else if (inbuf) {
- strncat(line2, line + i, 1);
- inbuf++;
- }
- switch (line[0]) { /* control character */
- case '?':{ /* interactive help entry */
- break; /* ignore */
- }
- case '@':{ /* start/end table */
- break; /* ignore */
- }
- case '#':{ /* latex table entry */
- break; /* ignore */
- }
- case '%':{ /* troff table entry */
- break; /* ignore */
- }
- case '^':{ /* html entry */
- break; /* ignore */
- }
- case '\n': /* empty text line */
- if (buf_head) { /* do we have a buffer? */
- /* paragraph finished, print it */
- clear_buffer(buf_head, b);
- buffer = buf_head = NULL;
- } else /* just copy the blank line */
- fputs(line, b);
- break;
- case ' ':{ /* normal text line */
- if (buf_head) { /* must be inserted in buffer ? */
- buffer->next = (struct BUFFER *) xmalloc(sizeof(struct BUFFER));
- buffer->next->prev = buffer;
- buffer = buffer->next;
- buffer->next = NULL;
- if (line2[0] == NUL) { /* line doesn't contain xref */
- buffer->content = (char *) xmalloc(strlen(line) + 1);
- strcpy(buffer->content, line);
- } else { /* line contains xref */
- buffer->content = (char *) xmalloc(strlen(line2) + 1);
- strcpy(buffer->content, line2);
- }
- } else /* no buffer, just copy */
- fputs(line, b);
- break;
- }
- default:
- if (isdigit((int) line[0])) { /* start of section */
- /* clear xref-list */
- xref_free();
- lastref = 0;
- if (buf_head) { /* do we have a buffer */
- /* paragraphs are not allways separated by a blank line */
- clear_buffer(buf_head, b);
- buffer = buf_head = NULL;
- }
- level = line[0] - '0';
-
- if (level > prev->level) /* going down */
- /* so write menu of previous node */
- refs(prev->line, b, "\n* Menu:\n\n", NULL, "* %s::\n");
- node = prev->next;
- if (!node->next) { /* last node ? */
- node_head(node->string, pre[level + 1], NULL, up[level], b);
- name_free(up);
- name_free(pre);
-
- /* next node will go up, no 'Next:' node */
- } else if (node->next->level < level)
- node_head(node->string, pre[level + 1], NULL, up[level], b);
-
- else {
- node_head(node->string, pre[level + 1], node->next->string, up[level], b);
- strcpy(pre[level + 1], node->string);
-
- /* next node will go down */
- if (level < node->next->level) {
- strcpy(up[level + 1], node->string);
- strcpy(pre[node->next->level + 1], node->string);
- }
- }
- prev = node;
- } else
- fprintf(stderr, "unknown control code '%c' in column 1, line %d\n",
- line[0], line_count);
- break;
- }
- }
-
- /*
- * write the header of an Info node, treat Top node specially
- */
- void node_head(node, prev, next, up, b)
- char *node, *prev, *next, *up;
- FILE *b;
- {
- /* eliminate leading spaces */
- while (node && isspace((int) *node))
- node++;
- while (next && isspace((int) *next))
- next++;
- while (prev && isspace((int) *prev))
- prev++;
- while (up && isspace((int) *up))
- up++;
-
- if (!prev) { /* Top node */
- int i;
- fprintf(b, "\nFile: %s, Node: Top, Prev: (dir), Next: %s, Up: (dir)\n\n", ofile, next);
- fprintf(b, "%s\n", title);
- for (i = 0; i < strlen(title); ++i)
- fprintf(b, "*");
- fprintf(b, "\n\n");
- return;
- }
- fprintf(b, "\n\nFile: %s, ", ofile);
- fprintf(b, "Node: %s, Prev: %s, Up: %s", node, prev, up);
-
- if (next)
- fprintf(b, ", Next: %s\n\n", next);
- else
- fputs("\n\n", b);
- }
-
- /*
- * allocate memory for the node titles (up and prev)
- * need at most maxlevel+Top+(dir) entries
- */
- char **name_alloc __PROTO((void))
- {
- char **a;
- int i;
-
- a = (char **) xmalloc((maxlevel + 2) * sizeof(char *));
- for (i = 0; i <= maxlevel + 1; i++)
- a[i] = (char *) xmalloc(MAX_LINE_LEN+1);
- return a;
- }
-
- /*
- * free node names
- */
- void name_free(names)
- char **names;
- {
- int i;
-
- for (i = 0; i <= maxlevel + 1; i++)
- free(names[i]);
- free(names);
- }
-
- /*
- * reformat the buffered lines
- */
- void clear_buffer(buf_head, b)
- struct BUFFER *buf_head;
- FILE *b;
- {
- struct BUFFER *run;
- int in_line = 0; /* offset into current line */
- int in_buf = 0; /* offset into buffer */
- int i, todo;
- char c;
-
- /* for all buffer entries */
- for (run = buf_head; run->next; run = run->next) {
-
- /* unprinted characters */
- todo = strlen(run->next->content);
-
- /* eliminate new-lines */
- if (run->next->content[todo - 1] == '\n')
- run->next->content[--todo] = NUL;
-
- while (todo)
- if (79 - in_line > todo) { /* buffer fits into line */
- fprintf(b, "%s", run->next->content + in_buf);
- in_line += todo;
- todo = in_buf = 0;
-
- } else { /* buffer must be split over lines */
-
- /* search for whitespace to split at */
- for (i = 79 - in_line; i > 2; --i)
- if (isspace((int) (run->next->content[in_buf + i]))) {
- char *beginnote, *linestart;
- c = run->next->content[in_buf + i - 1];
- if (c == '.') /* don't split at end of sentence */
- continue;
- if (c == ' ') /* ditto */
- continue;
-
- /* dont break xref */
- /* search for xref in current line */
- linestart = run->next->content + in_buf;
- beginnote = strstr(linestart, "(*note");
- while (beginnote && beginnote < linestart + i) {
- /* don't split if it didn't fit into the line as a whole */
- if (strchr(beginnote, ')') > linestart + i)
- break;
- /* xref is complete, maybe there's another one? */
- beginnote = strstr(beginnote + 1, "(*note");
- }
-
- /* unbalanced xref ? */
- if (beginnote && beginnote < linestart + i)
- continue;
-
- break;
- }
- if (i > 2) { /* found a point to split buffer */
- fprintf(b, "%.*s\n", i, run->next->content + in_buf);
- todo -= i;
- in_buf += i;
- in_line = 0;
- } else { /* try with a new line */
- fputs("\n", b);
- in_line = 0;
- }
- }
- }
- if (in_line) /* paragraph ended incomplete line */
- fputs("\n", b);
- fputs("\n", b);
-
- /* free the buffer */
- for (run = run->prev; run->prev; run = run->prev) {
- free(run->next->content);
- free(run->next);
- run->next = NULL;
- }
- if (buf_head->next) {
- free(buf_head->next->content);
- free(buf_head->next);
- buf_head->next = NULL;
- }
- free(buf_head);
- }
-
- /*
- * test whether topic is allready referenced in node
- */
- int inxreflist(reflist)
- struct LIST *reflist;
- {
- struct XREFLIST *run;
-
- for (run = refhead; run->next; run = run->next)
- if (run->next->ref == reflist)
- return TRUE;
- return FALSE;
- }
-
- /*
- * free the list of xrefs
- */
- void xref_free __PROTO((void))
- {
- struct XREFLIST *lastref;
-
- for (lastref = refhead; lastref->next; lastref = lastref->next);
- if (lastref != refhead)
- for (lastref = lastref->prev; lastref->prev; lastref = lastref->prev)
- free(lastref->next);
- if (refhead->next)
- free(refhead->next);
- refhead->next = NULL;
- }
-